<template>
    <div class="browser">
        <browser-header />
        <browser-option @touch="touch" />
        <div class="browser-wrapper">
            <!-- 布局 -->
            <browser-layout-info :max-height="window.height - 100" :max-width="window.width" @to="to" @download="download"
                @rm="rm" @rename="rename" @copy-link="copyLink" v-if="layout === SettingLayoutEnum.INFO" />
            <browser-layout-table :max-height="window.height - 100" :max-width="window.width" @to="to" @download="download"
                @rm="rm" @rename="rename" @copy-link="copyLink" v-else-if="layout === SettingLayoutEnum.TABLE" />
        </div>
        <browser-view />
    </div>
</template>
<script lang="ts">
import { useBrowserStore } from "../store/BrowserStore";
import MessageUtil from "@/utils/MessageUtil";
import { mapState } from "pinia";
import { defineComponent } from "vue";
import { useWindowSize } from '@vueuse/core'
import FileListItem from "@/module/driver/domain/FileListItem";
import { useTaskStore } from "@/module/task/store/TaskStore";
import { useFileOpenEvent } from "@/global/BeanFactory";
import { useLocalSettingStore } from "@/module/setting/store/LocalSettingStore";
import SettingLayoutEnum from "@/module/setting/enumeration/SettingLayoutEnum";
import { useLoadingStore } from "@/store/LoadingStore";
import MessageBoxUtil from "@/utils/MessageBoxUtil";
import BrowserUtil from "@/utils/BrowserUtil";

// 组件
import BrowserHeader from './header.vue';
import BrowserOption from './option.vue';
import BrowserView from './view.vue';

// 布局
import BrowserLayoutInfo from './layout/info.vue';
import BrowserLayoutTable from './layout/table.vue';

export default defineComponent({
    name: 'browser',
    components: { BrowserHeader, BrowserOption, BrowserLayoutInfo, BrowserView, BrowserLayoutTable },
    data: () => ({
        window: useWindowSize(),
        SettingLayoutEnum
    }),
    computed: {
        ...mapState(useBrowserStore, ['path', 'storage', 'back', 'pathSplit']),
        ...mapState(useLocalSettingStore, ['downloadPath', 'layout'])
    },
    created() {
        let id = this.$route.params.id as string;
        if (!useBrowserStore().init(id)) {
            MessageUtil.error("初始化浏览器失败");
            this.$router.back();
            return;
        }
        useBrowserStore().render();
    },
    methods: {
        to(item: FileListItem) {
            if (item.folder) {
                useBrowserStore().to(item.path);
            } else {
                this.open(item);
            }
        },
        open(item: FileListItem) {
            useFileOpenEvent.emit(item);
        },
        download(item: FileListItem) {
            if (item.folder) {
                MessageUtil.error("文件夹暂不支持下载");
                return;
            }
            MessageUtil.info("开始下载");
            useTaskStore().download({
                name: `下载【${item.name}】`,
                run: (progress, success, fail) => {
                    useBrowserStore().driver.read<ArrayBuffer>(item.path, (current, total) => {
                        progress(current, total);
                    }).then(content => {
                        window.preload.saveFile(item.name, this.downloadPath, content, e => {
                            if (e) {
                                fail();
                                MessageUtil.error("下载文件错误", e);
                            }
                            success();
                            MessageUtil.success("下载完成");
                        });
                    }).catch(e => {
                        MessageUtil.error("下载文件错误", e);
                        fail();
                    });
                },
            })
        },
        async rm(items: Array<FileListItem>) {
            for (let item of items) {
                try {
                    useLoadingStore().start(`正在删除【${item.name}】`);
                    await useBrowserStore().driver.rm(item.path);
                    MessageUtil.success("删除成功");
                } catch (e) {
                    MessageUtil.error("删除失败", e);
                }
            }
            useLoadingStore().close();
            useBrowserStore().render();
        },
        touch(name: string) {
            let path = useBrowserStore().resolve(name);
            useFileOpenEvent.emit({
                name,
                path,
                folder: true,
                size: 0,
                updateTime: '',
                extra: 'folder'
            });
        },
        rename(item: FileListItem) {
            MessageBoxUtil.prompt(`请输入新的文件${item.folder ? '夹' : ''}名`,
                `重命名文件${item.folder ? '夹' : ''}`, {
                confirmButtonText: '重命名',
                inputValue: item.name
            }).then(value => {
                if (value.trim() === '') {
                    MessageUtil.warning("请输入正确的文件名");
                    return;
                }
                if (/[\/:*?\"<>|]/.test(value)) {
                    MessageUtil.warning("文件名不能包含【\\\\/:*?\"<>|】这些非法字符");
                    return;
                }
                useTaskStore().download({
                    name: `将【${item.name}】重命名为【${value}】`,
                    run: (_progress, success, fail) => {
                        useLoadingStore().start("重命名");
                        useBrowserStore().driver.rename(item.name, value, useBrowserStore().path)
                            .then(() => {
                                MessageUtil.success("重命名成功");
                                success();
                                useBrowserStore().render();
                            }).catch(e => {
                                MessageUtil.error("重命名失败", e);
                                fail();
                            }).finally(() => useLoadingStore().close());
                    }
                })
            })
        },
        copyLink(item: FileListItem) {
            if (item.folder) {
                MessageUtil.error("文件夹无法获取外链");
                return;
            }
            BrowserUtil.copy(useBrowserStore().driver.getFileDownloadLink(item.path));
        }
    }
});
</script>
<style lang="less">
.browser {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;

    .browser-wrapper {
        position: absolute;
        top: 85px;
        left: 7px;
        right: 7px;
        bottom: 7px;
    }
}
</style>